#!/usr/bin/python
# coding:utf-8

import json
import cmd

from sql_rice import sql_parse
from sql_rice import gui
from sql_rice import rules


class DSLRicer(cmd.Cmd):

    def __init__(self, stdout=None):
        cmd.Cmd.__init__(self, stdout=stdout)
        self.config = {}
        self.in_block = ''

    def _eval(self, word, args):
        if args == 'begin':
            self.in_block = word
            self.config[word] = []
        elif args.startswith('ref'):
            ref, path = args.split()
            path = path.replace('"', '')
            with open(path) as f:
                self.config[word] = f.read()
        elif self.in_block == word:
            self.config[word].append(word + ' ' + args)

    def do_display(self, args):
        self.config['display'] = args

    def do_select(self, args):
        self._eval('select', args)

    def do_insert(self, args):
        self._eval('insert', args)

    def do_update(self, args):
        self._eval('update', args)

    def do_delete(self, args):
        self._eval('delete', args)

    def do_end(self, args):
        if self.in_block:
            self.config[self.in_block] = '\n'.join(self.config[self.in_block])
        self.in_block = ''

    def default(self, line):
        if self.in_block:
            self.config[self.in_block].append(line)
        #else:
            #self.stdout.write("WARNING: '%s' is not a valid command" % line)

    def do_dict(self, args):
        self.config['dict'] = args

    def do_rules(self, args):
        self.config['rules'] = args
        
    parse_line = cmd.Cmd.onecmd


class Ricer(object):

    def __init__(self):
        self.sentence = None
        self.widgets = []

    def parse(self, select, insert, update, delete, data_dict):
        self.sentence = sql_parse.SqlParser(select,
                        generate_insert=(insert == 'auto'),
                        generate_update=(update == 'auto'),
                        generate_delete=(delete == 'auto'))
        if  insert not in ('auto', 'off'):
            self.sentence.insert_query = insert
        if update not in ('auto', 'off'):
            self.sentence.update_query = update
        if delete not in ('auto', 'off'):
            self.sentence.delete_query = delete
        table = self.sentence.tables[0]
        for f in self.sentence.fields:
            rule = rules.search(f)
            w = gui.create_widget_info(f, table, data_dict)
            self.widgets.append(w)

    def dict_(self):
        statement = {}
        statement['select'] = dict(sql=self.sentence.sql,
                                    params=self.sentence.params,
                                    fields = self.sentence.fields)
        statement['update'] = dict(sql=self.sentence.update_query,
                                    params=self.sentence.params,
                                    fields=self.sentence.fields)
        statement['insert'] = dict(sql=self.sentence.insert_query,
                                    params=self.sentence.params,
                                    fields=self.sentence.fields)
        statement['delete'] = dict(sql=self.sentence.delete_query,
                                    params=self.sentence.params,
                                    fields=self.sentence.fields)
            
        return dict(statement=statement, widgets=self.widgets)
        

def load_dictionary(dictionary):
    with open(dictionary) as f:
        json_obj = json.load(f)
    return json_obj


def setup_models(ruledb):
    rules.metadata.bind = 'sqlite:///%s' % ruledb
    rules.setup_all()


def compile_rice(data_dict, ruledb, sql, output):
    setup_models(ruledb)
    dsr = DSLRicer()
    if isinstance(sql, str) or isinstance(sql, str):
        sql = sql.split('\n')
    for line in sql:
        dsr.parse_line(line)
    select = dsr.config.get('select')
    insert = dsr.config.get('insert', 'auto')
    update = dsr.config.get('update', 'auto')
    delete = dsr.config.get('delete', 'auto')
    rice = Ricer()
    rice.parse(select, insert, update, delete, data_dict)
    rice = rice.dict_()
    rice['display'] = dsr.config.get('display', 'form')
    json.dump(rice, output, indent=2)
    

def main(dictionary, rules, sqlfile, outfile):
    data_dict = load_dictionary(dictionary)
    with open(sqlfile) as f:
        sql = f.readlines()
    with open(outfile, 'w') as f:
        compile_rice(data_dict, rules, sql, f)


main.__annotations__ = dict(
    dictionary = 'Data dict',
    rules = 'rule database',
    sqlfile = 'file contains sqlrice script',
    outfile = 'filename to save file')
    

if __name__ == '__main__':
    import plac
    plac.call(main)
